#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define db double
using namespace std;
ll n,m,L,V;
struct Car
{
    ll d,v,a;
}c[100005];
ll pos[100005];
int cnt = 0;
struct Inv
{
    ll L,R;
}t[100005];
bool cmp(Inv x,Inv y)
{
    return x.R < y.R;
}
int main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        cnt = 0;
        scanf("%lld%lld%lld%lld",&n,&m,&L,&V);
        for (int i = 1;i <= n;i++)
        {
            scanf("%lld%lld%lld",&c[i].d,&c[i].v,&c[i].a);
        }
        for (int i = 1;i <= m;i++)
        {
            scanf("%lld",&pos[i]);
        }
        int ans = 0;
        ll rgt = 0;
        for (int i = 1;i <= n;i++)
        {
            if (c[i].a == 0)
            {
                if (c[i].v > V)
                {
                    if (pos[m] >= c[i].d)
                    {
                        ans++;
                        rgt = max(rgt,c[i].d);
                        //cout << i << endl;
                    }
                }
            }
            else if (c[i].a > 0)
            {
                if (c[i].v > V)
                {
                    if (pos[m] >= c[i].d)
                    {
                        ans++;
                        rgt = max(rgt,c[i].d);
                        //cout << i << endl;
                    }
                }
                else
                {
                    ll dis = V * V - c[i].v * c[i].v;
                    if ((pos[m] - c[i].d) * 2 * c[i].a > dis)
                    {
                        ans++;
                        rgt = max(rgt,c[i].d + dis);
                        //cout << i << endl;
                    }
                }
            }
            else
            {
                if (c[i].v > V)
                {
                    db dis = 1.0 * (V * V - c[i].v * c[i].v) / (2 * c[i].a);
                    int p1 = lower_bound(pos + 1,pos + m + 1,c[i].d + dis) - pos;
                    int p2 = lower_bound(pos + 1,pos + m + 1,c[i].d) - pos;
                    //cout << p1 << " " << p2 << endl;
                    if (p2 < p1)
                    {
                        ans++;
                        cnt++;
                        t[cnt].L = p2,t[cnt].R = p1 - 1;
                        //cout << i << endl;
                    }
                }
            }
        }
        printf("%d ",ans);
        if (cnt)
        {
            sort(t + 1,t + cnt + 1,cmp);
            int res = 1,mx = t[1].R;
            for (int i = 2;i <= cnt;i++)
            {
                if (t[i].L >= t[i - 1].L)
                {
                    if (mx < t[i].L)
                    {
                        mx = t[i].R;
                        res++;
                    }
                }
            }
            //cout << rgt << " " << pos[mx] << " " << mx << " " << endl;
            if (pos[mx] < rgt)
            {
                res++;
            }
            printf("%d\n",m - res);
        }
        else
        {
            printf("%d\n",m - (ans > 0));
        }
    }
    return 0;
}
